package com.app.shop.config.filter;

import com.app.shop.util.UserEntity;
import com.app.shop.entity.SysMenu;
import com.app.shop.util.JwtTokenUtils;
import com.app.shop.util.LoginUtil;
import io.jsonwebtoken.Claims;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


/**
 * @Author:aha
 * @Description:
 * token的校验
 * 该类继承自BasicAuthenticationFilter，在doFilterInternal方法中，
 * 从http头的Authorization 项读取token数据，然后用Jwts包提供的方法校验token的合法性。
 * 如果校验通过，就认为这是一个取得授权的合法请求
 * @Date: 2018/8/9 16:26
 * @Modified By:
 */
public class JWTAuthenticationFilter extends BasicAuthenticationFilter {

    public JWTAuthenticationFilter(AuthenticationManager authenticationManager){
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        String header = request.getHeader(JwtTokenUtils.TOKEN_HEADER);

        //增加微信请求鉴权操作，如果微信登录进行微信鉴权，鉴权成功后使用openID构造token保证openID永久访问权限
        // 如果请求头中没有Authorization信息则直接放行了
        if(header == null || !header.startsWith(JwtTokenUtils.TOKEN_PREFIX)){
            //throw new AccessDeniedException("登陆状态失效，请重新登陆！");
            //throw new EntryPointUnauthorizedHandler();
            chain.doFilter(request,response);
            return;
        }

        // 如果请求头中有token，则进行解析，并且设置认证信息
        UsernamePasswordAuthenticationToken authenticationToken = getAuthentication(header);
        if(authenticationToken==null){
            //throw new AccessDeniedException("登陆状态失效，请重新登陆！");
            chain.doFilter(request,response);
            return;
        }

        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        chain.doFilter(request,response);
    }

    /**
     *这里从token中获取用户信息并新建一个token
     */
    private UsernamePasswordAuthenticationToken getAuthentication(String header) {

        String token = header.replace(JwtTokenUtils.TOKEN_PREFIX, "");
        String usernameFromToken = JwtTokenUtils.getUsernameFromToken(token);

        if (usernameFromToken != null) {
            //从令牌解析出用户工号和用户编码
            Claims claims=JwtTokenUtils.getClaimsFromToken(token);
            UserEntity userEntity=new UserEntity();
            userEntity.setUsername(claims.get("username").toString());
            if(claims.containsKey("userId")) {
                userEntity.setUserId(Integer.parseInt(claims.get("userId").toString()));
            }
            //构造用户角色信息，用于URL权限校验
//            List<GrantedAuthority> auths = new ArrayList();
//            if(LoginUtil.getMenuList(userEntity.getUserId())!=null) {
//                for (SysMenu sysMenu : LoginUtil.getMenuList(userEntity.getUserId())) {
//                    auths.add(new SimpleGrantedAuthority(sysMenu.getMenuCode()));
//                }
//            }
            //根据用户编号将用户权限重新赋予系统
            return new UsernamePasswordAuthenticationToken(userEntity, null, null);
        }
        return null;
    }
}
